package xiaojian.toolkit.jmx.model;

import java.util.Arrays;
import javax.management.MBeanAttributeInfo;
import javax.management.ObjectName;

public class AttributesSnapshot {
	private final String _name;
	private Unit[] _units;

	private static String genArrayString(Object value) {
		Class<?> elementType = value.getClass().getComponentType();
		if (!elementType.isPrimitive()) {
			return Arrays.toString((Object[]) value);
		}
		if (elementType.equals(Boolean.TYPE)) {
			return Arrays.toString((boolean[]) value);
		}
		if (elementType.equals(Byte.TYPE)) {
			return Arrays.toString((byte[]) value);
		}
		if (elementType.equals(Short.TYPE)) {
			return Arrays.toString((short[]) value);
		}
		if (elementType.equals(Integer.TYPE)) {
			return Arrays.toString((int[]) value);
		}
		if (elementType.equals(Long.TYPE)) {
			return Arrays.toString((long[]) value);
		}
		if (elementType.equals(Character.TYPE)) {
			return Arrays.toString((char[]) value);
		}
		if (elementType.equals(Float.TYPE)) {
			return Arrays.toString((float[]) value);
		}
		if (elementType.equals(Double.TYPE)) {
			return Arrays.toString((double[]) value);
		}
		return null;
	}

	public static class Unit {
		private final ObjectName _objectName;
		private final AttrValue[] _attrValues;

		public static class AttrValue {
			private final MBeanAttributeInfo _info;
			private final Object _value;

			public AttrValue(MBeanAttributeInfo info, Object value) {
				this._info = info;
				this._value = value;
			}

			public MBeanAttributeInfo getAttributeInfo() {
				return this._info;
			}

			public Object getValue() {
				return this._value;
			}

			public String getValueAsText() {
				return null != this._value ? this._value.toString()
						: this._value.getClass().isArray() ? AttributesSnapshot
								.genArrayString(this._value) : "(null)";
			}

			public String toString() {
				return "[info=" + this._info + ", value=" + getValueAsText()
						+ "]";
			}
		}

		public ObjectName getObjectName() {
			return this._objectName;
		}

		public AttrValue[] getAttrValues() {
			return this._attrValues;
		}

		public Unit(ObjectName on, AttrValue... values) {
			this._objectName = on;
			this._attrValues = values;
		}

		public String toString() {
			return "[on=" + this._objectName + ", values="
					+ Arrays.toString(this._attrValues) + "]";
		}
	}

	public String getName() {
		return this._name;
	}

	public Unit[] getAttrUnits() {
		return this._units;
	}

	public AttributesSnapshot(String name, Unit... units) {
		this._name = name;
		this._units = units;
	}

	public String toString() {
		return "attrsSnapshot [name=" + this._name + ", units="
				+ Arrays.toString(this._units) + "]";
	}
}
